<template>
  <div>
    <el-upload
      accept=".mp3, .m4a, .aac, .mp4, .m4v"
      :before-upload="beforeUpload"
      :http-request="upload"
      :show-file-list="false"
      :disabled="disabled"
      style="display: inline-block"
      class="m-x-12"
    >
      <el-tooltip placement="bottom">
        <template #content>
          可上传本地录音录像，支持上传的
          <br />音频格式为：mp3、m4a、aac
          <br />
          视频格式为：mp4、m4v
        </template>
        <el-button type="primary" style="font-size: 12px" :disabled="disabled">
          上传录音录像
        </el-button>
      </el-tooltip>
    </el-upload>

<!--    <div-->
<!--      v-if="props.modelValue && props.isShow"-->
<!--      style="margin-top: 10px; width: 100%"-->
<!--    >-->
<!--      <input-->
<!--        disabled="false"-->
<!--        v-model="props.modelValue"-->
<!--        placeholder-class="input-placeholder"-->
<!--        style="width: 80%; padding: 10px; margin-right: 10px"-->
<!--        id="myInput"-->
<!--      />-->
<!--    </div>-->
    <!-- 文件列表 -->
    <transition-group
      class="upload-file-list el-upload-list el-upload-list--text"
      name="el-fade-in-linear"
      tag="ul"
      v-if="props.modelValue && props.isShow"
    >
      <li class="el-upload-list__item ele-upload-list__item-content">
        <el-link :underline="false" target="_blank">
          <span class="el-icon-document"> {{ props.modelValue }} </span>
        </el-link>

      </li>

    </transition-group>

<!--    <template #default="scope">-->
      <video
        v-if="props.modelValue && props.isShow"
        controls
        muted
        :width="200" :height="200"
        type="video/mp4" :src="props.modelValue">
        Your browser doesn't support the video tag.

      </video>
    <!-- 删除    -->
    <span v-if="props.modelValue && props.isShow" @click="handleDelete">
             <svg t="1723452326752" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1976" width="32" height="32"><path d="M681.6256 188.2624H335.1552c-25.4976 0-46.1312-20.6336-46.1312-46.1312s20.6336-46.1312 46.1312-46.1312h346.5216c25.4976 0 46.1312 20.6336 46.1312 46.1312s-20.6848 46.1312-46.1824 46.1312z" fill="#59ADF8" p-id="1977"></path><path d="M891.2896 229.9392H127.4368c-25.2416 0-47.3088 19.456-48.0768 44.7488-0.768 26.112 20.1728 47.5648 46.1312 47.5648h53.8624v527.104c0 46.0288 37.3248 83.3536 83.3536 83.3536h491.3664c46.0288 0 83.3536-37.3248 83.3536-83.3536V322.2528h51.9168c25.2416 0 47.3088-19.456 48.0768-44.7488 0.768-26.112-20.1728-47.5648-46.1312-47.5648zM429.312 688.128c0 25.4976-20.6336 46.1312-46.1312 46.1312-25.4976 0-46.1312-20.6336-46.1312-46.1312V466.8416c0-25.4976 20.6336-46.1312 46.1312-46.1312 25.4976 0 46.1312 20.6336 46.1312 46.1312v221.2864z m250.4192 0c0 25.4976-20.6336 46.1312-46.1312 46.1312-25.4976 0-46.1312-20.6336-46.1312-46.1312V466.8416c0-25.4976 20.6336-46.1312 46.1312-46.1312 25.4976 0 46.1312 20.6336 46.1312 46.1312v221.2864z" fill="#2595E8" p-id="1978"></path><path d="M837.4272 672.6144V322.2528h51.9168c25.2416 0 47.3088-19.456 48.0768-44.7488 0.768-26.112-20.1728-47.5648-46.1312-47.5648H127.4368c-25.2416 0-47.3088 19.456-48.0768 44.7488-0.768 26.112 20.1728 47.5648 46.1312 47.5648h53.8624v527.104c0 46.0288 37.3248 83.3536 83.3536 83.3536h203.4688c153.1392-39.2704 284.2112-133.376 371.2512-260.096z m-249.9584-205.7728c0-25.4976 20.6336-46.1312 46.1312-46.1312 25.4976 0 46.1312 20.6336 46.1312 46.1312v221.2864c0 25.4976-20.6336 46.1312-46.1312 46.1312-25.4976 0-46.1312-20.6336-46.1312-46.1312V466.8416z m-204.288 267.4176c-25.4976 0-46.1312-20.6336-46.1312-46.1312V466.8416c0-25.4976 20.6848-46.1312 46.1312-46.1312 25.4976 0 46.1312 20.6336 46.1312 46.1312v221.2864c0 25.4464-20.6336 46.1312-46.1312 46.1312z" fill="#3A9CED" p-id="1979"></path><path d="M127.4368 229.9392c-25.2416 0-47.3088 19.456-48.0768 44.7488-0.768 26.112 20.1728 47.5648 46.1312 47.5648h53.8624V721.92c54.784-4.2496 107.6736-15.3088 157.7472-32.3584 0-0.4608-0.0512-0.9728-0.0512-1.4336V466.8416c0-25.4976 20.6848-46.1312 46.1312-46.1312 25.4976 0 46.1312 20.6336 46.1312 46.1312v182.9888a647.00416 647.00416 0 0 0 158.1056-117.248V466.8416a46.1056 46.1056 0 0 1 79.4112-31.8976 640.98816 640.98816 0 0 0 89.2416-204.9536l-628.6336-0.0512z" fill="#59ADF8" p-id="1980"></path><path d="M563.456 96H335.1552c-25.4976 0-46.1312 20.6336-46.1312 46.1312s20.6336 46.1312 46.1312 46.1312h181.2992a648.3456 648.3456 0 0 0 47.0016-92.2624zM79.36 274.688c-0.768 26.112 20.1728 47.5648 46.1312 47.5648h53.8624V459.776c125.0816-43.6224 232.6016-124.7232 309.0944-229.8368H127.4368c-25.2928 0-47.3088 19.5072-48.0768 44.7488z" fill="#6BC2FC" p-id="1981"></path></svg>
        </span>

<!--    </template>-->
    <br />
    <el-dialog
      v-model="dialogVisible"
      :fullscreen="true"
      :show-close="false"
      custom-class="dispute-upload-dialog"
    >
      <div class="center">
        <div class="fz-18 ellipsis">正在上传：{{ fileData.name }}</div>
        <el-progress
          :text-inside="true"
          :stroke-width="16"
          :percentage="percentage"
        />
        <el-button style="margin-top: 10px" @click="cancel">取消上传</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { getToken } from "@/utils/auth";
import axios from "axios";
const { proxy } = getCurrentInstance();
const emit = defineEmits();
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const props = defineProps({
  modelValue: [String, Object, Array],
  // 是否显示删除
  isShow: {
    type: Boolean,
    default: true,
  },
});
const beforeUpload = (file) => {
  const mimeTypes = [
    "audio/mpeg",
    "audio/x-m4a",
    "audio/aac",
    "video/mp4",
    "video/x-m4v",
  ];
  if (!mimeTypes.includes(file.type)) {
    proxy.$modal.msgError({
      type: "error",
      message: "只能上传 MP3、M4A、AAC、MP4、M4V 格式的文件",
      duration: 6000,
    });
    return false;
  }
  if (file.size / 1024 / 1024 / 1024 > 1.5) {
    proxy.$modal.msgError("文件大小不能超过 1.5G");
    proxy.$modal.msgError({
      type: "error",
      message: "文件大小不能超过 1.5G",
      duration: 6000,
    });
    return false;
  }
  return true;
};

const dialogVisible = ref(false);
const cancelUpload = ref(false);
let controller = null;
const chunkSize = 1 * 1024 * 1024; // 切片大小1M
const percentage = ref(0);
const fileData = ref({
  name: "",
  size: 0,
  type: "",
  suffix: "",
  md5: "",
});
const cancel = () => {
  const formData = new FormData();
  formData.append("name", fileData.value.name);
  formData.append("md5", fileData.value.md5);
  dialogVisible.value = false;
  cancelUpload.value = true;
  controller?.abort();
  axios
    .post(baseUrl + "/system/oss/endUpload", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
        Authorization: "Bearer " + getToken(),
      },
    })
    .then(() => {
      proxy.$modal.msgSuccess("取消上传");
    });
};

let counter = 0;
const getFileMd5 = () => {
  let guid = (+new Date()).toString(32);
  for (let i = 0; i < 5; i++) {
    guid += Math.floor(Math.random() * 65535).toString(32);
  }
  return "wu_" + guid + (counter++).toString(32);
};

const updateUrl = (fileUrl) => {
  // console.log("fileUrl===>>", fileUrl);
  axios.post("saveUrl", {
    fileName: fileData.value.name,
    fileUrl,
  });
};

// 上传切片
const uploadChunkFile = async (i, fileObj, chunkCount) => {
  // console.log(i, fileObj);
  const start = i * chunkSize;
  const end = Math.min(fileData.value.size, start + chunkSize);
  console.log(start, end);
  const chunkFile = fileObj.slice(start, end);
  
  console.log("chunkFile=>", chunkFile);
  const formData = new FormData();
  formData.append("encrypt", "true");
  formData.append("name", fileData.value.name);
  formData.append("md5", fileData.value.md5);
  formData.append("file", chunkFile, String(i + 1));
  formData.append("size", fileObj.size);
  formData.append("chunk", i);
  formData.append("chunks", chunkCount);
console.log(chunkFile)
  controller = new AbortController();
  return await axios
    .post(baseUrl + "/system/oss/uploadBigFile", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
        Authorization: "Bearer " + getToken(),
      },
      onUploadProgress: (data) => {
        console.log(data)
        percentage.value = Number(((Math.min(fileData.value.size, start + data.loaded) /fileData.value.size) * 100).toFixed(2));
      },
      signal: controller.signal,
    })
    .then((res) => {
      // console.log(res, "0000000000000000");
      if (res.data.code === 200) {
        return res;
      } else {
        // 关闭弹框
        dialogVisible.value = false;
        // 结束循环
        cancelUpload.value = true;
        proxy.$modal.msgError({
          message: `${fileData.value.name}上传失败`,
          title: "提示",
        });
      }
      // updateUrl(res.data);
    })
    .catch((err) => {
      // 关闭弹框
      dialogVisible.value = false;
      // 结束循环
      cancelUpload.value = true;
      proxy.$modal.msgError({
        message: `${fileData.value.name}上传失败`,
        title: "提示",
      });
    });
};

// 计算切片数量
const batchUpload = async (fileObj) => {
  percentage.value = 0;
  dialogVisible.value = true;
  cancelUpload.value = false;
  const chunkCount = Math.ceil(fileData.value.size / chunkSize); // 切片数量
  // console.log("切片数量", chunkCount);
  fileData.value.md5 = getFileMd5(); // 文件唯一标识
  for (let i = 0; i < chunkCount; i++) {
    if (cancelUpload.value) return;
    const res = await uploadChunkFile(i, fileObj, chunkCount);
    // console.log(res, "分割线--------------", fileData.value);

    if (res && res.data.code === 200 && res.data.data.url) {
      proxy.$modal.msgSuccess({
        message: `${fileData.value.name}上传成功`,
        title: "提示",
      });
      dialogVisible.value = false;
      emit("update:modelValue", res.data.data.url);
      emit("videoUrl", res.data.data.url);
    } else if (res && res.data.code !== 200) {
      dialogVisible.value = false;
      proxy.$modal.msgError({
        message: `${fileData.value.name}上传失败`,
        title: "提示",
      });
    }

    // if (i === chunkCount - 1) {
    //   console.log("循环上传");
    //   return;
    //   setTimeout(() => {
    //     dialogVisible.value = false;
    //     proxy.$modal.msgSuccess({
    //       message: `${fileData.value.name}上传成功`,
    //       title: "提示",
    //     });
    //     axios
    //       .post("/system/oss/uploadTest", {
    //         folder: fileData.value.md5,
    //       })
    //       .then((res) => {
    //         console.log(res);
    //         return;
    //         updateUrl(res.data);
    //       });
    //   }, 500);
    // }
  }
};
function handleDelete() {
  emit("update:modelValue", "");
  return false;
}
// 选择文件
const disabled = ref(false);
const upload = async (file) => {
  console.log(file);
  console.log(file);
  const fileObj = file.file;
  const formData = new FormData();
  formData.append("file", file.file);
  const nameList = fileObj.name.split(".");
  fileData.value.name = fileObj.name;
  fileData.value.size = fileObj.size;
  fileData.value.type = fileObj.type;
  fileData.value.suffix = nameList[nameList.length - 1];

  // console.log("比较大小", chunkSize, fileData.value.size);
  if (chunkSize > fileData.value.size) {
    proxy.$modal.loading("正在上传文件，请稍候...");
    // 说明是小文件只有1M
    disabled.value = true;
    axios
      .post(baseUrl + "/system/oss/upload", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
          Authorization: "Bearer " + getToken(),
        },
      })
      .then((res) => {
        proxy.$modal.msgSuccess({
          message: `${fileData.value.name}上传成功`,
          title: "提示",
        });
        proxy.$modal.closeLoading();
        emit("update:modelValue", res.data.data.url);
        emit("videoUrl", res.data.data.url);
      })
      .catch(() => {
        proxy.$modal.msgError({
          message: `${fileData.value.name}上传失败`,
          title: "提示",
        });
        proxy.$modal.closeLoading();
      })
      .finally(() => (disabled.value = false));
    return;
  }
  batchUpload(fileObj);
};
</script>

<style lang="scss">
.dispute-upload-dialog {
  background: none;
}
</style>

<style lang="scss" scoped>
.center {
  color: #fff;
  width: 50%;
  text-align: center;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>
